package com.pubinfo.passbook.common.service.contract.impl;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pubinfo.passbook.common.entity.*;
import com.pubinfo.passbook.common.enums.OrgIdEnum;
import com.pubinfo.passbook.common.enums.SyncContractTypeEnum;
import com.pubinfo.passbook.common.model.vo.contract.ProjectNotClearVo;
import com.pubinfo.passbook.common.model.vo.contract.SyncContractCostVo;
import com.pubinfo.passbook.common.model.vo.contract.SyncContractProjectVo;
import com.pubinfo.passbook.common.model.vo.contract.SyncContractVo;
import com.pubinfo.passbook.common.service.contract.TContractBaseService;
import com.pubinfo.passbook.common.service.contract.TContractProjectCostItemsService;
import com.pubinfo.passbook.common.service.contract.TContractSyncService;
import com.pubinfo.passbook.common.service.contract.TContractWbsProjectService;
import com.pubinfo.passbook.common.service.contract.TContractProjectNotClearService;
import com.pubinfo.passbook.common.service.master.TSystemTaskLogService;
import com.pubinfo.passbook.common.thread.TaskExecutor;
import com.pubinfo.passbook.common.utils.HttpTools;
import com.pubinfo.passbook.common.utils.TimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.RoundingMode;
import java.util.*;

/**
 * @description 同步数据
 */
@Slf4j
@Service
public class TContractSyncServiceImpl implements TContractSyncService {
  
  @Resource
  private TContractBaseService contractBaseService;
  @Resource
  TContractProjectNotClearService projectNotClearService;
  @Resource
  private TContractWbsProjectService contractWbsProjectService;
  
  @Resource
  private TContractProjectCostItemsService contractProjectCostItemsService;
  @Resource
  TSystemTaskLogService logService;
  /**
   * 同步
   */
  @Transactional
  @Override

  public void syncContract(String taskId) {
    
    log.info("-----同步合同-----");
    
    long startSync = System.currentTimeMillis();
    QueryWrapper<TContractBase> qw = new QueryWrapper<>();
    qw.lambda().orderByDesc(TContractBase::getCreateTime).last("limit 1");
    TContractBase lastOne = contractBaseService.getOne(qw);
    String queryStartTime = Objects.isNull(lastOne) ? "19700102" : TimeUtils.dateFormat3(lastOne.getCreateTime());
    TTaskLog taskLog = new TTaskLog();
    String endDate = TimeUtils.dateFormat3(TimeUtils.getDayEnd());
    String postUrl = String.format(
        "http://134.96.245.118:7001/czxt/action/zjcw/contract/queryContractRecord.do?type=%s&beginDate=%s&endDate=%s",
        SyncContractTypeEnum.CONTRACT.getKey(),
        queryStartTime, endDate
    );
  
    log.info("请求地址:{}", postUrl);
    taskLog.setTaskId(taskId).setName("syncContract").setStartDate(DateUtil.parse(queryStartTime)).setEndDate(DateUtil.parse(endDate));
  
    String result = HttpTools.httpGet(postUrl);
    JSONObject resultJson = JSONObject.parseObject(result);
    Set<String> contractSet = new HashSet<>();
    if (200 == (resultJson.getInteger("code"))) {
  
      List<SyncContractVo> syncContractVos = JSONArray.parseArray(resultJson.getString("records"), SyncContractVo.class);
      taskLog.setAcceptTotalCount(syncContractVos.size()).setSuccessCount(syncContractVos.size());
      if (CollectionUtils.isEmpty(syncContractVos)) {
        return;
      }
      setContractBase(contractSet, syncContractVos);
     // updateContractBase(contractSet, syncContractVos);
    } else {
      log.error(resultJson.getString("msg"));
    }
    Long responseTime = System.currentTimeMillis() - startSync;
    taskLog.setResponseTime(responseTime).setStatus(1);
    logService.save(taskLog);
    log.info("同步合同成功,耗时：{} ms", responseTime);
    log.info("已撤消的合同：{} ", contractSet);
  }
  
  private void updateContractBase(Set<String> contractSet, List<SyncContractVo> syncContractVos) {
    
    TaskExecutor<SyncContractVo> taskExecutor = new TaskExecutor<>(syncContractVos.size());
    for (SyncContractVo vo : syncContractVos) {
      try {
        taskExecutor.submit(base -> contractBaseService.lambdaUpdate().set(TContractBase::getDistrictCode, base.getQxbm()).set(TContractBase::getDistrictName, base.getQxmc()).eq(TContractBase::getContractCode, base.getContractCode()).update(), vo);
        //   contractBaseService.save(contractBase);
      } catch (DuplicateKeyException e) {
        log.error("合同【{}】已存在", vo.getContractCode());
      } catch (Exception e) {
        log.error("同步合同失败", e.getMessage());
        e.printStackTrace();
      }
    }
    taskExecutor.await();
    
  }
  
  private void setContractBase(Set<String> contractSet, List<SyncContractVo> syncContractVos) {
    
    TaskExecutor<TContractBase> taskExecutor = new TaskExecutor<>(syncContractVos.size());
    for (SyncContractVo vo : syncContractVos) {
      
      TContractBase contractBase = new TContractBase() {{
        setContractCode(vo.getContractCode());//合同编号
        setContractName(vo.getContractName());//合同名称
        setAccountCase(vo.getGszt());//帐套
        setCompany(vo.getPartAname());//合同本方单位
        setPartbName(vo.getPartBname());//合同对方单位
        setSourceStatus(vo.getStatus());
        setContractType(0);// 新过来的数据，设置为待处理。
        setContractDate(
            Objects.isNull(vo.getArchiveDate()) ?
                (Objects.isNull(vo.getSigndate()) ? vo.getCreateTime() : vo.getArchiveDate()) :
                vo.getArchiveDate()
        );//合同生效日期
        setContractYear(Objects.isNull(getContractDate()) ? null : TimeUtils.getDateYear(getContractDate()));//年份
        //如果源状态为已撤销，则设置为关闭状态
        if ("已撤销".equals(vo.getStatus())) {
          setStatus(20);
          contractSet.add(vo.getContractCode());
        }
        setContractAmount(vo.getTreadeSum().setScale(2, RoundingMode.HALF_UP));//合同金额
        setSocialCode(vo.getSocialCode());//税号
        setAccountName(vo.getAccountName());//收款方账户 开户名称
        setBankName(vo.getBankName());//收款方账户 开户行
        setBankAccounts(vo.getBankAccounts());//收款方账户 账号
        setDepartment(vo.getApplyDept());//承接部门
        setContractUserId(vo.getApplyUserId());//合同承办人编码
        setConsAddr(vo.getConsAddr());//地址
        setContractorUser(vo.getName());//承办人
        setCreateTime(vo.getCreateTime());//创建时间
        setUpdateTime(vo.getCreateTime());//更新时间
        setContractPhone(vo.getTelPhone());//合同手机号
        
        setCityCode(vo.getDsbm());//地市编码
        setOrgId(OrgIdEnum.getEnum(getCityCode()));//地区ID
        setCityName(vo.getDsmc());//地市名称
        setDistrictCode(vo.getQxbm());//区县编码
        setDistrictName(vo.getQxmc());//区县名称
      }};
      try {
        taskExecutor.submit(base -> contractBaseService.save(base), contractBase);
        //   contractBaseService.save(contractBase);
      } catch (DuplicateKeyException e) {
        log.error("合同【{}】已存在", vo.getContractCode());
      } catch (Exception e) {
        log.error("同步合同失败", e.getMessage());
        e.printStackTrace();
      }
    }
    taskExecutor.await();
  }
  private void setContractBaseStatus(List<SyncContractVo> syncContractVos) {
    for (SyncContractVo vo : syncContractVos) {
      contractBaseService.lambdaUpdate().set(TContractBase::getSourceStatus, vo.getStatus()).eq(TContractBase::getContractCode, vo.getContractCode()).update();
    }
  }
  
  /**
   * 同步合同运维项目
   */
  @Transactional
  @Override
  public void syncContractProject() {
  
    log.info("-----同步合同运维项目-----");
  
    long startSync = System.currentTimeMillis();
  
    QueryWrapper<TContractWbsProject> qw = new QueryWrapper<>();
    qw.lambda().orderByDesc(TContractWbsProject::getCreateTime).last("limit 1");
    TContractWbsProject lastOne = contractWbsProjectService.getOne(qw);
    String queryStartTime = Objects.isNull(lastOne) ? "19700101" : TimeUtils.dateFormat3(lastOne.getCreateTime());
  
    String url = String.format(
        "http://134.96.245.118:7001/czxt/action/zjcw/contract/queryContractRecord.do?type=%s&beginDate=%s&endDate=%s",
        SyncContractTypeEnum.YWXM.getKey(),
        queryStartTime,
        TimeUtils.dateFormat3(TimeUtils.getDayEnd())
    );
  
    String result = HttpTools.httpGet(url);
  
    JSONObject resultJson = JSONObject.parseObject(result);
    if (200 == (resultJson.getInteger("code"))) {
      List<SyncContractProjectVo> vos = JSONArray.parseArray(resultJson.getString("records"), SyncContractProjectVo.class);
    
      for (SyncContractProjectVo vo : vos) {
        TContractWbsProject wbsProject = new TContractWbsProject() {{
          setBillId(vo.getBillid());//项目ID
          setProjectCode(vo.getPosid());//项目编号
          setProjectName(vo.getPost1());//项目名称
          setProjectDate(vo.getPlanBeginDate());//立项日期
          setProjectAmount(vo.getApplySum());//立项金额
          setPlanBeginDate(vo.getPlanBeginDate());//计划开始时间
          setPlanEndDate(vo.getPlanendDate());//计划接结束时间
//                    setDepartment(vo.get  );//部门 todo
          setAdministrators(vo.getMakeUserName());//管理员
          setStatus(vo.getStatus());//状态
          setCreateTime(vo.getCreateTime());//创建时间
        }};
        try {
          contractWbsProjectService.save(wbsProject);
        } catch (DuplicateKeyException e) {
          log.error("合同运维项目【{}】已存在", wbsProject.getProjectCode());
          continue;
        } catch (Exception e) {
          log.error("同步合同运维项目失败 {}", e.getMessage());
        }
      }
    }
  
    log.info("同步合同运维项目成功,耗时：{} ms", System.currentTimeMillis() - startSync);
  
  }
  
  /**
   * 同步合同运维项目成本信息
   */
  @Transactional
  @Override
//  @Async("taskExecutor")
  public void syncContractCostItems() {
    
    log.info("-----同步合同运维项目成本信息-----");
    
    long startSync = System.currentTimeMillis();
//
//        QueryWrapper<TContractProjectCostItems> qw = new QueryWrapper<>();
//        qw.lambda().orderByDesc(TContractProjectCostItems::getCreateTime).last("limit 1");
//        TContractProjectCostItems lastOne = contractProjectCostItemsService.getOne(qw);
    // String queryStartTime = Objects.isNull(lastOne) ? "19700101" : TimeUtils.dateFormat3(lastOne.getCreateTime());
    
    String url = String.format(
        "http://134.96.245.118:7001/czxt/action/zjcw/contract/queryContractRecord.do?type=%s",
        SyncContractTypeEnum.YWXMCB.getKey()
    );
    
    String result = HttpTools.httpGet(url);
    
    JSONObject resultJson = JSONObject.parseObject(result);
    if (200 == (resultJson.getInteger("code"))) {
      List<SyncContractCostVo> vos = JSONArray.parseArray(resultJson.getString("records"), SyncContractCostVo.class);
      List<TContractProjectCostItems> costItems = new ArrayList<>();
      setContractCostItems(vos, costItems);
      //先删除数据库，再增加
      contractProjectCostItemsService.lambdaUpdate().remove();
      
      contractProjectCostItemsService.saveBatch(costItems);
      
    }
    
    log.info("同步合同运维项目成本信息成功,耗时：{} ms", System.currentTimeMillis() - startSync);
  }
  
  private void setContractCostItems(List<SyncContractCostVo> vos, List<TContractProjectCostItems> costItems) {
    
    for (SyncContractCostVo vo : vos) {
      
      TContractProjectCostItems costItem = new TContractProjectCostItems() {{
        setAccountCode(vo.getHkont());//会计科目编码
        setAccountName(vo.getKmmc());
        setAmount(vo.getDmbtr());//金额
        setUpdateTime(vo.getCreateTime());//更新时间
        setCreateTime(vo.getCreateTime());//创建时间
        setProjectCode(vo.getPosid());
        StringBuffer ids = new StringBuffer();
        ids.append(vo.getPosid()).append("-").append(vo.getHkont());
        setId(ids.toString());
      }};
      costItems.add(costItem);
      
    }
  }
  
  @Transactional
  @Override
  public void syncProjectNotClear() {
    
    long startSync = System.currentTimeMillis();
    String url = String.format(
        "http://134.96.245.118:7001/czxt/action/zjcw/contract/queryContractRecord.do?type=%s",
        SyncContractTypeEnum.YWXMWLWQMX.getKey()
    );
    String result = HttpTools.httpGet(url);
    JSONObject resultJson = JSONObject.parseObject(result);
    if (200 == (resultJson.getInteger("code"))) {
      List<ProjectNotClearVo> vos = JSONArray.parseArray(resultJson.getString("records"), ProjectNotClearVo.class);
      if (CollectionUtils.isEmpty(vos)) {
        log.info("没有查到数据！");
        return;
      }
      List<TContractProjectNotClear> projectNotClears = new ArrayList<>();
      setProjectNotClear(vos, projectNotClears);
      //先删除数据库，再增加
      projectNotClearService.lambdaUpdate().remove();
      projectNotClearService.saveBatch(projectNotClears);
      
    }
    
    log.info("同步合同运维项目成本信息成功,耗时：{} ms", System.currentTimeMillis() - startSync);
  }
  
  private void setProjectNotClear(List<ProjectNotClearVo> vos, List<TContractProjectNotClear> projectNotClears) {
    for (ProjectNotClearVo vo : vos) {
      TContractProjectNotClear costItem = new TContractProjectNotClear() {{
        setProjectCode(vo.getPosid());
        setProjectName(vo.getPost1());
        setWbsElement(vo.getProjk());
        setCompayCode(vo.getBukrs());
        setCertificateCode(vo.getBelnr());
        setYear(vo.getGjahr());
        setCertificateLine(vo.getBuzei());
        setSettleAccountsDate(vo.getAugdt());
        setClearingEntryDate(vo.getAugcp());
        setSettleAccounts(vo.getAugbl());
        setSymbol(vo.getShkzg());
        setAmount(vo.getDmbtr());
        setProjectText(vo.getSgtxt());
        setAccountCode(vo.getHkont());
        setPurchaseOrder(vo.getEbeln());
        setProfitCenter(vo.getPrctr());
        setCostCenter(vo.getKostl());
        setCreatetime(vo.getCreatetime());
        // BELNR||  BUZEI||GJAHR||BUKRS 唯一
        
        StringBuffer ids = new StringBuffer();
        ids.append(vo.getBelnr()).append("-").append(vo.getBuzei()).append("-").append(vo.getGjahr()).append("-").append(vo.getBukrs());
        setId(ids.toString());
        projectNotClears.add(this);
      }};
    }
  }
  
}




